package com.gitee.srurl.register;

import cn.hutool.core.collection.CollectionUtil;
import com.gitee.srurl.util.ThreadCloseUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 数据上报
 *
 * @author zxw
 * @date 2023/4/24 22:23
 */
@Slf4j
public class DataReportHandle {

    public static final List<IDataReport> dataReportList = new CopyOnWriteArrayList<>();

    private static final List<IDataReportListener> dataReportListenerList = new CopyOnWriteArrayList<>();

    private static ScheduledExecutorService executorService;

    /**
     * 注册上报
     *
     * @param dataReport 上报
     */
    public static synchronized void registerReport(IDataReport dataReport) {

        if (dataReport != null) {
            dataReportList.add(dataReport);
            log.info("dataReport 添加上报注册,当前注册上报数量:{}", dataReportList.size());
        }
    }

    /**
     * 取消注册
     */
    public static synchronized void unRegisterReport(IDataReport dataReport) {

        if (dataReport != null) {
            dataReportList.remove(dataReport);
            log.info("dataReport 取消上报注册,当前注册上报数量:{}", dataReportList.size());
        }
    }

    /**
     * 注册监听
     *
     * @param dataReportListener 上报监听
     */
    public static synchronized void registerReportListener(IDataReportListener dataReportListener) {

        if (dataReportListener != null) {
            dataReportListenerList.add(dataReportListener);
            log.info("dataReportListener 添加上报监听注册,当前注册上报监听数量:{}", dataReportListenerList.size());
        }
    }

    public static synchronized void unRegisterReportListener(IDataReportListener dataReportListener) {

        if (dataReportListener != null) {
            dataReportListenerList.remove(dataReportListener);
            log.info("dataReportListener 取消上报监听注册,当前注册上报监听数量:{}", dataReportListenerList.size());
        }
    }

    /**
     * 定时上报数据
     * 借鉴美团leaf
     */
    public static void start() {
        DataReportHandle.executorService = Executors.newSingleThreadScheduledExecutor(r -> {
            Thread thread = new Thread(r, "schedule-report");
            thread.setDaemon(true);
            return thread;
        });
        DataReportHandle.executorService.scheduleWithFixedDelay(() -> {
            log.debug("----->上报数据");
            if (CollectionUtil.isNotEmpty(DataReportHandle.dataReportList)
                    && CollectionUtil.isNotEmpty(DataReportHandle.dataReportListenerList)) {
                for (IDataReport iDataReport : DataReportHandle.dataReportList) {
                    try {
                        final String report = iDataReport.report();
                        String reportPath = null;
                        for (IDataReportListener iDataReportListener : DataReportHandle.dataReportListenerList) {
                            try {
                                reportPath = iDataReport.reportPath();
                                boolean listener = iDataReportListener.listener(reportPath, report);
                                if (!listener) {
                                    log.error("监听上报数据失败,上报地址:{},上报数据:{}", reportPath, report);
                                }
                            } catch (Exception e) {
                                log.error("监听上报数据失败,上报地址:{},上报数据:{},e:", reportPath, report, e);
                            }
                        }
                    } catch (Exception e) {
                        log.error("获取上报数据失败:", e);
                    }
                }
            }
            //每3s上报数据
        }, 1L, 3L, TimeUnit.SECONDS);
    }

    public static void stop() {
        ThreadCloseUtil.shutdownAndAwaitTermination(executorService);
    }
}
